﻿using System;
using MapDownloader.Core.MapProviders;
using MapDownloader.Core.Models;
using MongoDB.Bson;
using MongoDB.Driver;

namespace MapDownloader.Core.Storage
{
   public class MongoTileStorage : ITileStore
   {
      /// <summary>
      /// 连接字符串
      /// </summary>
      private static MongoClient _client;
      private static IMongoDatabase _database;
      public int DeleteOlderThan(DateTime date, int? type)
      {
         throw new NotImplementedException();
      }

      public BaseImage GetTileFromStore(long x, long y, int zoom, int type)
      {
         var collection = _database.GetCollection<MongoTileModel>("Map");
         var xFilter = Builders<MongoTileModel>.Filter.Eq("X", x);
         var yFilter = Builders<MongoTileModel>.Filter.Eq("Y", y);
         var zoomFilter = Builders<MongoTileModel>.Filter.Eq("Zoom", zoom);
         var typeFilter = Builders<MongoTileModel>.Filter.Eq("Type", type);
         var filter = Builders<MongoTileModel>.Filter.And(xFilter, yFilter, zoomFilter, typeFilter);
         var result = collection.Find(filter).FirstOrDefault();
         if (result?.Tile.Length > 0)
            if (BaseMapProvider.TileImageProxy != null)
               return BaseMapProvider.TileImageProxy.FromArray(result.Tile);
         return null;
      }

      public bool PutTileToStore(int type, TilePoint pos, byte[] tile)
      {
         var collection = _database.GetCollection<MongoTileModel>("Map");
         collection.InsertOne(new MongoTileModel() { X = pos.X, Y = pos.Y, Zoom = pos.Z, Type = type, Tile = tile });
         return true;

      }

      public void SetConnectionString(string con, string databaseName)
      {
         _client = new MongoClient(con);
         _database = _client.GetDatabase(databaseName??"map");
      }
   }

   internal class MongoTileModel
   {
      /// <summary>
      /// 
      /// </summary>
      public ObjectId _id { get; set; }
      /// <summary>
      /// 
      /// </summary>
      public int Type { get; set; }
      /// <summary>
      /// 
      /// </summary>
      public int Zoom { get; set; }
      /// <summary>
      /// 
      /// </summary>
      public long X { get; set; }
      /// <summary>
      /// 
      /// </summary>
      public long Y { get; set; }
      /// <summary>
      /// 
      /// </summary>
      public byte[] Tile { get; set; }
   }
}
